﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using System.IO;
using System.Text.RegularExpressions;
using System.Configuration;
using FastColoredTextBoxNS;
namespace SPEasyCode
{
    public partial class Form1 : Form
    {
        AutocompleteMenu popupMenu;
        AutocompleteMenu popupMenu2;
        string[] keywords = { "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while", "add", "alias", "ascending", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "remove", "select", "set", "value", "var", "where", "yield", "True", "False" };
        string[] methods = { "Equals()", "GetHashCode()", "GetType()", "ToString()" };
        string[] snippets = { ">>Foreach <%lists%>\n>>{\n^\n>>}", ">>Foreach <%fields%>\n>>{\n^\n>>}", ">>if(^value1==value2)\n>>{\n \n>>} \n >>else\n>>{\n\n>>}", ">>if(^value1!=value2)\n>>{\n\n>>} \n >>else\n>>{\n\n>>}", "<<Save(^fileName.cs)\n<<{ \n\n <<}" ,">>var ^x=0", ">>Set ^x=1"};
        string[] declarationSnippets = { 
               "public class ^\n{\n}", "private class ^\n{\n}", "internal class ^\n{\n}",
               "public struct ^\n{\n;\n}", "private struct ^\n{\n;\n}", "internal struct ^\n{\n;\n}",
               "public void ^()\n{\n;\n}", "private void ^()\n{\n;\n}", "internal void ^()\n{\n;\n}", "protected void ^()\n{\n;\n}",
               "public ^{ get; set; }", "private ^{ get; set; }", "internal ^{ get; set; }", "protected ^{ get; set; }","<%DataType%>^","<%ConvertTo%>^","<%FieldName%>^","<%fieldName%>^","<%InternalFieldName%>^","<%ListName%>^","<%ListTitle%>^","<%listName%>^","<%SPDataType%>^","<%RequiredField%>^","<%FieldTitle%>^","<%ListGuid%>^","<%FieldLookupListGuid%>^","<%FieldLookupListTitle%>^","<%FieldChoiseValues%>^","<%NumberFormat%>^"
               };

        public Form1()
        {
            InitializeComponent();
            //create autocomplete popup menu
            popupMenu = new AutocompleteMenu(this.txtTemplate);
            popupMenu.Items.ImageList = imageList1;
            popupMenu.SearchPattern = @"[\w\.:=!<>]";
            //
            BuildAutocompleteMenu();
            popupMenu2 = new AutocompleteMenu(this.txtTemplate);
            popupMenu2.MinFragmentLength = 2;
            var randomWords = new List<string>();

            randomWords.Add("SPAC all rights received");
            randomWords.Add("System");
            randomWords.Add("System.Collections.Generic");
            randomWords.Add("System.Linq");
            randomWords.Add("System.Text");
            randomWords.Add("SPweb");
            randomWords.Add("SPsite");

            //set words as autocomplete source
            popupMenu2.Items.SetAutocompleteItems(randomWords);
            //size of popupmenu
            popupMenu2.Items.MaximumSize = new System.Drawing.Size(200, 300);
            popupMenu2.Items.Width = 200;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.btnNext1.Enabled = false;
            this.btnUpdate.Enabled = false;
            this.btnNext2.Enabled = false;
            this.txtTemplatepath.Text = ConfigurationManager.AppSettings["TemplatePath"];
            this.txtDestinationFolder.Text = ConfigurationManager.AppSettings["DestinationPath"];
            this.txtSiteUrl.Text = ConfigurationManager.AppSettings["SPURL"];
            this.btnWrite.Enabled = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {


        }







        private void txtSiteUrl_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnLoadLists_Click(object sender, EventArgs e)
        {
            try
            {
                this.lstvAllLists.Items.Clear();
                this.lstvSelected.Items.Clear();
                //Code runs under elevated privileges
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite site = new SPSite(this.txtSiteUrl.Text))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            foreach (SPList list in web.Lists)
                            {
                                if (!string.IsNullOrEmpty(list.Title))
                                    this.lstvAllLists.Items.Add(list.Title);
                            }
                        }
                    }

                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed connecting to the SharePoint site url " + this.txtSiteUrl.Text);
            }

        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstvAllLists.SelectedItems)
            {
                lstvAllLists.Items.Remove(item);
                lstvSelected.Items.Add(item);
            }
            this.btnNext1.Enabled = this.lstvSelected.Items.Count > 0;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstvSelected.SelectedItems)
            {
                lstvSelected.Items.Remove(item);
                lstvAllLists.Items.Add(item);
            }
            this.btnNext1.Enabled = this.lstvSelected.Items.Count > 0;
        }

        void popupMenu_Opening(object sender, CancelEventArgs e)
        {
            //---block autocomplete menu for comments
            //get index of green style (used for comments)
            var iGreenStyle = 2;
            if (iGreenStyle >= 0)

                //current char (before caret)
                //var c = CurrentTB[CurrentTB.Selection.Start.iLine][CurrentTB.Selection.Start.iChar - 1];
                //green Style
                Range.ToStyleIndex(iGreenStyle);

        }

        private void btnLoadTemplate_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK) // Test result.
            {
                string file = openFileDialog1.FileName;
                try
                {
                    string text = File.ReadAllText(file);
                    this.rtbTemplate.Text = text;
                    this.txtTemplatepath.Text = file;
                }
                catch (IOException)
                {
                }

            }
            rtbTemplate.Font = new Font("Consolas", 9.5F);

            string tokens = string.Concat(@"\b(auto|string|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|extern|return|union|const|",
                     "float|short|unsigned|continue|for|signed|void|default|",
                     @"goto|sizeof|volatile|do|if|static|while|public|private|using|get|set|new|DateTime|namespace|partial|region|endregion|bool|try|catch|finaly|class)\b");
            Regex rex = new Regex(tokens);
            MatchCollection mc = rex.Matches(rtbTemplate.Text);


            int StartCursorPosition = rtbTemplate.SelectionStart;
            foreach (Match m in mc)
            {
                int startIndex = m.Index;
                int StopIndex = m.Length;
                rtbTemplate.Select(startIndex, StopIndex);
                rtbTemplate.SelectionColor = Color.Blue;
                rtbTemplate.SelectionStart = StartCursorPosition;
                rtbTemplate.SelectionColor = Color.Black;
            }
            colorText(@"#", Color.Blue, rtbGeneratedCode);
            colorText(@"{", Color.Blue, rtbTemplate);
            colorText(@"}", Color.Blue, rtbTemplate);
            colorText(Constants.InstructionIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.ForEachIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.LoopStartIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.LoopEndIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.SaveEndIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.SaveIdentifier, Color.LightSkyBlue, rtbTemplate);
            colorText(Constants.SaveStartIdentifier, Color.LightSkyBlue, rtbTemplate);

            SearchAndHighlight(Constants.DataTypeIdentifier, Color.LightSteelBlue, rtbTemplate);
            SearchAndHighlight(Constants.FieldNameIdentifier, Color.LightSkyBlue, rtbTemplate);
            SearchAndHighlight(Constants.FieldIdentifier, Color.LightSteelBlue, rtbTemplate);
            SearchAndHighlight(Constants.ListKeyIdentifier, Color.LightSteelBlue, rtbTemplate);
            SearchAndHighlight(Constants.ListNameIdentifier, Color.LightSkyBlue, rtbTemplate);
            SearchAndHighlightComment(@"//", Color.Green, rtbTemplate);
            SearchAndHighlightComment(@"///", Color.Green, rtbTemplate);
            this.rtbGeneratedCode.Text = string.Empty;
            this.txtTemplate.Text = this.rtbTemplate.Text;
            this.txtFinalCode.Text = "";
            this.btnUpdate.Enabled = true;

        }

        public void colorText(string text, Color color, RichTextBox rtb)
        {
            SearchAndHighlight(text, color, rtb);
        }



        private void SearchAndHighlightComment(string searchText, Color color, RichTextBox rtb)
        {
            if (searchText.Length > 0)
            {
                int index = -1;
                int searchStart = 0;
                while ((index = rtb.Find(searchText, searchStart, RichTextBoxFinds.None)) > -1 && rtb.Text.Length > searchStart)
                {
                    index = rtb.Find(searchText, searchStart, RichTextBoxFinds.None);
                    int line = rtb.GetLineFromCharIndex(index);
                    int first = rtb.GetFirstCharIndexFromLine(line);
                    int last = rtb.Lines[line].Length;

                    rtb.Select(first, last);
                    rtb.SelectionColor = color;
                    searchStart = index + searchText.Length;
                }

                //Regex regKeywords = new Regex("\\\\.*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                //Match regMatch;

                //for (regMatch = regKeywords.Match(m_strLine); regMatch.Success; regMatch = regMatch.NextMatch())
                //{
                //    // Process the words
                //    int nStart = m_nLineStart + regMatch.Index;
                //    int nLenght = regMatch.Length;
                //    SelectionStart = nStart;
                //    SelectionLength = nLenght;
                //    SelectionColor = color;
                //}
            }
        }
        private void SearchAndHighlight(string searchText, Color color, RichTextBox rtb)
        {
            if (searchText.Length > 0)
            {
                int index = -1;
                int searchStart = 0;
                while ((index = rtb.Find(searchText, searchStart, RichTextBoxFinds.None)) > -1 && rtb.Text.Length > searchStart)
                {
                    rtb.Select(index, searchText.Length);
                    rtb.SelectionColor = color;
                    searchStart = index + searchText.Length;
                }
            }
        }

        private void SearchAndHighlight(string searchText, bool background, Color color, RichTextBox rtb)
        {
            if (searchText.Length > 0)
            {
                int index = -1;
                int searchStart = 0;
                while ((index = rtb.Find(searchText, searchStart, RichTextBoxFinds.None)) > -1)
                {
                    rtb.Select(index, searchText.Length);
                    if (background)
                        rtb.SelectionBackColor = color;
                    else
                        rtb.SelectionColor = color;
                    searchStart = index + searchText.Length;
                }
            }
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            this.rtbGeneratedCode.Font = new Font("Consolas", 9.5F);

            GlobalData.FinalOutPut = new StringBuilder();
            GlobalData.Init();
            string filePath = this.txtTemplatepath.Text;
            string url = txtSiteUrl.Text;
            List<string> list = new List<string>();
            foreach (ListViewItem item in lstvSelected.Items)
            {
                list.Add(item.Text);
            }
            this.rtbGeneratedCode.Text = TemplateProcesser.GenerateCode(filePath, list, url);

            string tokens = string.Concat(@"\b(auto|string|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|extern|return|union|const|",
          "float|short|unsigned|continue|for|signed|void|default|",
          @"goto|sizeof|volatile|do|if|static|while|public|private|using|get|set|new|DateTime|namespace|partial|region|endregion|bool|try|catch|finaly|class)\b");
            Regex rex = new Regex(tokens);
            MatchCollection mc = rex.Matches(rtbGeneratedCode.Text);


            colorText(@"{", Color.Blue, rtbGeneratedCode);
            colorText(@"}", Color.Blue, rtbGeneratedCode);
            colorText(@"#", Color.Blue, rtbGeneratedCode);
            colorText(Constants.InstructionIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.ForEachIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.LoopStartIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.LoopEndIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.SaveEndIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.SaveIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            colorText(Constants.SaveStartIdentifier, Color.LightSkyBlue, rtbGeneratedCode);

            SearchAndHighlight(Constants.DataTypeIdentifier, Color.LightSteelBlue, rtbGeneratedCode);
            SearchAndHighlight(Constants.FieldNameIdentifier, Color.LightSkyBlue, rtbGeneratedCode);
            SearchAndHighlight(Constants.FieldIdentifier, Color.LightSteelBlue, rtbGeneratedCode);
            SearchAndHighlight(Constants.ListKeyIdentifier, Color.LightSteelBlue, rtbGeneratedCode);
            SearchAndHighlight(Constants.ListNameIdentifier, Color.LightSkyBlue, rtbGeneratedCode);

            SearchAndHighlightComment(@"//", Color.Green, rtbGeneratedCode);
            SearchAndHighlightComment(@"///", Color.Green, rtbGeneratedCode);

            int StartCursorPosition = rtbGeneratedCode.SelectionStart;
            foreach (Match m in mc)
            {
                int startIndex = m.Index;
                int StopIndex = m.Length;
                rtbGeneratedCode.Select(startIndex, StopIndex);
                rtbGeneratedCode.SelectionColor = Color.Blue;
                rtbGeneratedCode.SelectionStart = StartCursorPosition;
                rtbGeneratedCode.SelectionColor = Color.Black;
            }

            this.txtFinalCode.Text = rtbGeneratedCode.Text;
            //this.btnWrite.Enabled = this.txtFinalCode.Text.Length > 0 && Path.IsPathRooted(this.txtDestinationFolder.Text);

        }



        private void readFile()
        {

            //this.richTextBox1.Text;


        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.txtFinalCode.Text.Length > 0)
                    TemplateIO.WriteFile(this.txtFinalCode.Text, this.txtDestinationFolder.Text, 0);
            }
            catch
            {

                MessageBox.Show("SPAC encounter a problem.Please try generating code and then writing");
            }
        }

        private void btnOutputFilePath_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();

            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK) // Test result.
            {
                string file = dialog.SelectedPath;
                try
                {

                    this.txtDestinationFolder.Text = file;

                }
                catch (IOException)
                {
                }
            }



        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            TemplateIO.Write(this.txtTemplate.Text, this.txtTemplatepath.Text);
            this.btnNext2.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstvAllLists.Items)
            {
                lstvAllLists.Items.Remove(item);
                lstvSelected.Items.Add(item);
            }

            this.btnNext1.Enabled = this.lstvSelected.Items.Count > 0;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstvSelected.Items)
            {
                lstvSelected.Items.Remove(item);
                lstvAllLists.Items.Add(item);
            }
            this.btnNext1.Enabled = this.lstvSelected.Items.Count > 0;
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            this.Code.Width = this.Width;
            this.Code.Height = this.Height;
            this.lstvAllLists.Height = this.Height - 75;
            this.lstvSelected.Height = this.Height - 75;
            this.lstvAllLists.Top = 75;
            this.lstvSelected.Top = 75;


            this.btnNext1.Left = this.Width - 20 - this.btnNext1.Width;
            this.btnBack1.Left = this.Width - 25 - this.btnNext1.Width - this.btnBack1.Width;
            this.btnLoadLists.Left = this.Width - 30 - this.btnNext1.Width - this.btnBack1.Width - this.btnLoadLists.Width;
            this.txtSiteUrl.Width = this.Width - 55 - this.btnNext1.Width - this.btnBack1.Width - this.btnLoadLists.Width;
            this.btnNext2.Left = this.Width - 20 - this.btnNext1.Width;
            this.btnUpdate.Left = this.Width - 35 - this.btnNext1.Width - this.btnBack1.Width - this.btnUpdate.Width - this.btnNew.Width;
            this.btnNew.Left = this.Width - 30 - this.btnNext1.Width - this.btnBack1.Width - this.btnUpdate.Width;

            this.btnWrite.Left = this.Width - 30 - this.btnNext3.Width - this.btnBack3.Width - this.btnWrite.Width;
            this.btnGenerate.Left = this.Width - 35 - this.btnNext3.Width - this.btnBack3.Width - this.btnWrite.Width - this.btnGenerate.Width;
            this.btnOutputFilePath.Left = this.Width - 40 - this.btnNext3.Width - this.btnBack3.Width - this.btnWrite.Width - this.btnGenerate.Width - this.btnOutputFilePath.Width;
            this.txtDestinationFolder.Width = this.Width - 55 - this.btnNext3.Width - this.btnBack3.Width - this.btnWrite.Width - this.btnGenerate.Width - this.btnOutputFilePath.Width;
            this.btnLoadTemplate.Left = this.Width - 45 - this.btnNext1.Width - this.btnBack1.Width - this.btnUpdate.Width - this.btnLoadTemplate.Width - this.btnNew.Width;
            this.txtTemplatepath.Width = this.Width - (this.btnNext1.Width + this.btnBack1.Width + this.btnUpdate.Width + this.btnLoadTemplate.Width + 55 + this.btnNew.Width);
            this.btnBack2.Left = this.Width - 25 - this.btnNext1.Width - this.btnBack1.Width;
            this.btnNext3.Left = this.Width - 20 - this.btnNext1.Width;
            this.btnBack3.Left = this.Width - 25 - this.btnNext1.Width - this.btnBack1.Width;
            this.txtSiteUrl.Top = 20;
            this.btnBack1.Top = 20;
            this.btnBack2.Top = 20;
            this.btnNew.Top = 20;
            this.btnBack3.Top = 20;
            this.btnNext3.Top = 20;
            this.btnLoadLists.Top = 20;

            this.btnNext1.Top = 20;
            this.btnNext2.Top = 20;
            this.btnUpdate.Top = 20;
            this.btnLoadTemplate.Top = 20;
            this.txtTemplatepath.Top = 20;
            this.txtDestinationFolder.Top = 20;
            this.btnGenerate.Top = 20;
            this.btnOutputFilePath.Top = 20;
            this.btnWrite.Top = 20;
            this.pictureBox1.Top = this.lstvAllLists.Top;
            this.pictureBox1.Height = this.lstvAllLists.Height;
            pictureBox1.Visible = this.pictureBox1.Width + this.lstvAllLists.Width + this.lstvSelected.Width + 200 < this.Width;

            this.txtTemplate.Height = this.Height - 100;
            this.txtTemplate.Width = this.Width;
            this.txtTemplate.Dock = DockStyle.Bottom;
            this.rtbTemplate.Height = this.Height - 80;
            this.rtbTemplate.Width = this.Width;
            this.rtbGeneratedCode.Height = this.rtbTemplate.Height;
            this.txtFinalCode.Height = this.txtTemplate.Height;
            rtbGeneratedCode.Width = this.rtbTemplate.Width;
            rtbGeneratedCode.Height = this.rtbTemplate.Height;
            //this.btnBack1.Left = this.btnNext1.Left - 15;
        }

        private void btnBack1_Click(object sender, EventArgs e)
        {
        }

        private void btnNext1_Click(object sender, EventArgs e)
        {
            this.Code.SelectedTab = this.tabTemplate; ;
        }

        private void btnBack2_Click(object sender, EventArgs e)
        {
            this.Code.SelectedTab = this.tabList; ;
        }

        private void btnNext2_Click(object sender, EventArgs e)
        {
            this.Code.SelectedTab = this.tabCode;
        }

        private void tabCode_Click(object sender, EventArgs e)
        {

        }

        private void btnBack3_Click(object sender, EventArgs e)
        {
            this.Code.SelectedTab = this.tabTemplate; ;
        }

        private void rtbTemplate_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void lstvSelected_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void txtTemplatepath_TextChanged(object sender, EventArgs e)
        {

        }

        private void tabList_Click(object sender, EventArgs e)
        {

        }

        private void BuildAutocompleteMenu()
        {
            List<AutocompleteItem> items = new List<AutocompleteItem>();

            foreach (var item in snippets)
                items.Add(new SnippetAutocompleteItem(item) { ImageIndex = 1 });
            foreach (var item in declarationSnippets)
                items.Add(new DeclarationSnippet(item) { ImageIndex = 0 });
            foreach (var item in methods)
                items.Add(new MethodAutocompleteItem(item) { ImageIndex = 2 });
            foreach (var item in keywords)
                items.Add(new AutocompleteItem(item));

            items.Add(new InsertSpaceSnippet());
            items.Add(new InsertSpaceSnippet(@"^(\w+)([=<>!:]+)(\w+)$"));
            items.Add(new InsertEnterSnippet());

            //set as autocomplete source
            popupMenu.Items.SetAutocompleteItems(items);
        }

        /// <summary>
        /// This item appears when any part of snippet text is typed
        /// </summary>
        class DeclarationSnippet : SnippetAutocompleteItem
        {
            public DeclarationSnippet(string snippet)
                : base(snippet)
            {
            }

            public override CompareResult Compare(string fragmentText)
            {
                var pattern = Regex.Replace(fragmentText, FastColoredTextBoxNS.FindForm.RegexSpecSymbolsPattern, "\\$0");
                if (Regex.IsMatch(Text, "\\b" + pattern, RegexOptions.IgnoreCase))
                    return CompareResult.Visible;
                return CompareResult.Hidden;
            }
        }

        /// <summary>
        /// Divides numbers and words: "123AND456" -> "123 AND 456"
        /// Or "i=2" -> "i = 2"
        /// </summary>
        class InsertSpaceSnippet : AutocompleteItem
        {
            string pattern;

            public InsertSpaceSnippet(string pattern)
                : base("")
            {
                this.pattern = pattern;
            }

            public InsertSpaceSnippet()
                : this(@"^(\d+)([a-zA-Z_]+)(\d*)$")
            {
            }

            public override CompareResult Compare(string fragmentText)
            {
                if (Regex.IsMatch(fragmentText, pattern))
                {
                    Text = InsertSpaces(fragmentText);
                    if (Text != fragmentText)
                        return CompareResult.Visible;
                }
                return CompareResult.Hidden;
            }

            public string InsertSpaces(string fragment)
            {
                var m = Regex.Match(fragment, pattern);
                if (m == null)
                    return fragment;
                if (m.Groups[1].Value == "" && m.Groups[3].Value == "")
                    return fragment;
                return (m.Groups[1].Value + " " + m.Groups[2].Value + " " + m.Groups[3].Value).Trim();
            }

            public override string ToolTipTitle
            {
                get
                {
                    return Text;
                }
            }
        }

        /// <summary>
        /// Inerts line break after '}'
        /// </summary>
        class InsertEnterSnippet : AutocompleteItem
        {
            Place enterPlace = Place.Empty;

            public InsertEnterSnippet()
                : base("[Line break]")
            {
            }

            public override CompareResult Compare(string fragmentText)
            {
                var r = Parent.Fragment.Clone();
                while (r.Start.iChar > 0)
                {
                    if (r.CharBeforeStart == '}')
                    {
                        enterPlace = r.Start;
                        return CompareResult.Visible;
                    }

                    r.GoLeftThroughFolded();
                }

                return CompareResult.Hidden;
            }

            public override string GetTextForReplace()
            {
                //extend range
                Range r = Parent.Fragment;
                Place end = r.End;
                r.Start = enterPlace;
                r.End = r.End;
                //insert line break
                return Environment.NewLine + r.Text;
            }

            public override void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
            {
                base.OnSelected(popupMenu, e);
                if (Parent.Fragment.tb.AutoIndent)
                    Parent.Fragment.tb.DoAutoIndent();
            }

            public override string ToolTipTitle
            {
                get
                {
                    return "Insert line break after '}'";
                }
            }
        }

        private void txtTemplate_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == (Keys.K | Keys.Control))
            {
                //forced show (MinFragmentLength will be ignored)
                popupMenu2.Show(true);
                e.Handled = true;
            }
        }

        private void txtTemplate_TextChanged(object sender, TextChangedEventArgs e)
        {
            int textLength = TemplateIO.LineCount(this.txtTemplatepath.Text);
            this.btnNext2.Enabled = this.txtTemplate.Text.Length > 0 && this.txtTemplate.Text.IndexOf(">>") > -1 && this.txtTemplate.Text.IndexOf("SPAC all rights received") > -1 && textLength > 0;
            //this.btnUpdate.Enabled = this.btnNext2.Enabled;


            //string value = string.Empty;
            //foreach (value
            //if (value.IndexOf("var") > -1 && value.IndexOf("=") > -1)
            //{
            //   string  tempVariable = value.Split('=')[1].Trim();
            //   string tempVaribaleName = value.Trim().Split('=')[0].Replace("var", string.Empty).Replace("=", string.Empty).Replace(">>", string.Empty).Trim();
            //    if (GlobalData.SPACVariables.ContainsKey(tempVaribaleName))
            //    {
            //        GlobalData.SPACVariables[tempVaribaleName] = tempVariable;
            //    }
            //    else
            //    {
            //        GlobalData.SPACVariables.Add(tempVaribaleName, tempVariable);
            //    }
            //}

        }

        private void txtDestinationFolder_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            this.saveFileDialog1.ShowDialog();
            this.txtTemplatepath.Text = saveFileDialog1.FileName;
            this.txtTemplate.Text = "//SPAC all rights received.";
            this.btnUpdate.Enabled = true;
            this.btnNext2.Enabled = false;
        }

        private void txtFinalCode_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.btnWrite.Enabled = this.txtFinalCode.Text.IndexOf("<<Save") > -1;
        }


    }

}
